/*Copyright (C) 2009 - 2011 MASSART GAUTHIER

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "../headers.h"

/* Menu principal de l'éditeur de niveaux
*/
void excit_menu_level_editor() {
	int choix;

	do {
		clear();
		choix = afficher_menu_jeu("Créer un niveau dans un pack existant\n"
															"Editer un niveau existant\n"
															"Editer la liste des packs\n"
															"Retour\n",
															TITRE_EXCIT);

		if(choix == 1) {
			excit_create_level();
		}
		else if(choix == 2) {
			excit_choose_level_pack_to_edit();
		}
		else if(choix == 3) {
			edit_level_pack("Excit");
		}
	}
	while(choix != 4);
}

void excit_create_level() {
	EXCIT_CASE_T matrix[EXCIT_MAT_X][EXCIT_MAT_Y];
	EXCIT_INF_T inf;
	char author_name[50], lvl_name[50];
	char root_pack_filename[300], new_pack_filename[256];
	int choix;
	bool loop = true;

	excit_init_to_default(matrix, &inf);

	if(excit_level_editor(matrix, &inf)) {
		excit_edit_level_info(lvl_name, author_name, 50);

		while(loop == true) {
			clear();
			afficher_titre(TITRE_EXCIT);
			CSLP_ColorText(CT);
			addstr("\n\n Entrez le nom du pack de niveaux où sauvegarder le niveau : ");
			lire(new_pack_filename, 256);

			sprintf(root_pack_filename, "%s%s%s", PACKS_PERSO_ROOT, new_pack_filename, ".pak");

			if(fichier_existe(root_pack_filename) == false) {
				clear();
				choix = afficher_menu("Oui\nNon\n", "Ce pack de niveaux n'existe pas, le créer?\n", TITRE_EXCIT);

				if(choix == 1) {
					if(!add_pack_auto("Excit", new_pack_filename)) {
						CSLP_ColorText(COLOR_GREEN);
						addstr("\n\n La création du pack à réussi.");
						loop = false;
						getch();
					}
				}
			}
			else {
				loop = false;
			}
		}

		if(excit_append_to_lvl_pack(root_pack_filename, matrix, lvl_name, author_name)) {
			addstr("\n\n La sauvegarde a échoué.");
			getch();
		}
		else {
			CSLP_ColorText(COLOR_GREEN);
			addstr("\n\n Niveau sauvegardé avec succès.");
			getch();
		}
	}
}

/* Permet de choisir le pack de niveaux à éditer
*/
void excit_choose_level_pack_to_edit() {
	char root_pack_filename[300];

	if(!choose_pack("Excit", root_pack_filename)) {
		CSLP_ColorText(COLOR_GREEN);
		addstr("\n\n Le pack a bien été chargé.");
		getch();
	}

	excit_choose_level_to_edit(root_pack_filename);
}

/* Permet de choisir le niveau à éditer
*/
void excit_choose_level_to_edit(char *filename) {
	EXCIT_CASE_T matrix[EXCIT_MAT_X][EXCIT_MAT_Y];
	EXCIT_INF_T inf;
	int choix, nb_levels, i = 0;
	char level[1000][50] = {{0}}, author[1000][100] = {{0}}, level_list[50000], lvl_name[50], author_name[100], transfert[100];

	strcpy(level_list, "\0");

	nb_levels = get_level_list(filename, level, author);

	if(!nb_levels) {
		CSLP_ColorText(COL_ERREUR);
		addstr("\n\n Le format du fichier est invalide ou le pack est vide.");
		return;
	}

	while(i != nb_levels) {
		sprintf(transfert, "%s\n", level[i]);
		strcat(level_list, transfert);
		i++;
	}

	strcat(level_list, "Retour\n");
	clear();
	choix = afficher_menu(level_list, "Choisissez le niveau à éditer :", TITRE_EXCIT);

	if(choix <= nb_levels) {
		excit_init_to_default(matrix, &inf);

		if(excit_parse_file(filename, level, choix - 1, matrix, &inf)) {
			CSLP_ColorText(COL_ERREUR);
			addstr("\n Erreur : Le format du niveau est invalide.");
		}
		else {
			if(excit_level_editor(matrix, &inf)) {
				clear();
				excit_edit_level_info(lvl_name, author_name, 50);
				excit_save_level(filename, matrix, author_name, lvl_name);
			}
		}
	}
}

int excit_level_editor(EXCIT_CASE_T matrix[EXCIT_MAT_X][EXCIT_MAT_Y], EXCIT_INF_T *inf) {
	bool loop = true;
	int key, choix, retval = 0;
	IPoint cursor_pos;

	curs_set(0);
	excit_display_editor(matrix, inf);
	cursor_pos.x = 1;
	cursor_pos.y = 1;
	move(cursor_pos.y + EXCIT_MAT_ORG_Y, cursor_pos.x + EXCIT_MAT_ORG_X);
	curs_set(1);
	refresh();

	while(loop) {
		key = getch();

		if(key == EXCIT_KEY_QUIT) {
			clear();
			choix = afficher_menu("Sauvegarder et quitter\n"
			"Quitter sans sauvegarder\n"
			"Annuler\n",
			"Que voulez-vous faire?\n",
			TITRE_EXCIT);

			if(choix == 1) {
				loop = false;
				retval = 1;
			}
			else if(choix == 2) {
				loop = false;
				retval = 0;
			}
			else {
				excit_display_editor(matrix, inf);
				curs_set(1);
			}
		}
		else if(key == touche_haut || key == touche_bas || key == touche_droite || key == touche_gauche) {
			excit_move_cursor(key, &cursor_pos);
		}
		else {
			excit_edit_matrix(matrix, key, &cursor_pos, inf);
		}
	}

	curs_set(0);
	return retval;
}

void excit_edit_level_info(char *lvl_name, char *author_name, size_t len) {
	bool loop = true;

	clear();
	afficher_titre(TITRE_EXCIT);
	CSLP_ColorText(CT);
	addstr(" Entrez le nom de l'auteur du niveau :\n");
	get_player_name(0, prenom);
	strcpy(author_name, prenom);
	addstr("\n\n");

	while(loop == true) {
		clear_line();
		addstr(" Entrez le nom du niveau : ");
		lire(lvl_name, len);

		if(lvl_name[0] != '\0') {
			loop = false;
		}
	}
}

int excit_append_to_lvl_pack(char *lvl_pack_filename, EXCIT_CASE_T matrix[EXCIT_MAT_X][EXCIT_MAT_Y], const char *lvl_name, const char *author_name) {

	if(!fichier_existe(lvl_pack_filename)) {
		CSLP_ColorText(COL_ERREUR);
		addstr("\n Le pack de niveaux n'a pas pu être ouvert.");
		return 1;
	}

	excit_save_level(lvl_pack_filename, matrix, author_name, lvl_name);
	return 0;
}

/* Permet de modifier la position du curseur sous ordre
** du joueur
*/
void excit_move_cursor(int key, IPoint *cursor_pos) {
	if(key == touche_bas) {
		if(cursor_pos->y < EXCIT_MAT_Y - 2) {
			cursor_pos->y++;
		}
	}
	else if(key == touche_haut) {
		if(cursor_pos->y > 1) {
			cursor_pos->y--;
		}
	}
	else if(key == touche_droite) {
		if(cursor_pos->x < EXCIT_MAT_X - 2) {
			cursor_pos->x++;
		}
	}
	else if(key == touche_gauche) {
		if(cursor_pos->x > 1) {
			cursor_pos->x--;
		}
	}

	move(cursor_pos->y + EXCIT_MAT_ORG_Y, cursor_pos->x + EXCIT_MAT_ORG_X);
}

/* Permet d'éditer la matrice sous ordre du joueur
*/
void excit_edit_matrix(EXCIT_CASE_T matrix[EXCIT_MAT_X][EXCIT_MAT_Y], int key, IPoint *cursor_pos, EXCIT_INF_T *inf) {
	EXCIT_CASE_T *cel;

	cel = &matrix[cursor_pos->x][cursor_pos->y];

	if(key == EXCIT_KEY_EMUR) {

		if(*cel == EXCIT_JOUEUR) {
			inf->pos_joueur.x = -1;
			inf->pos_joueur.y = -1;
		}
		else if(*cel == EXCIT_OBJECTIF) {
			inf->pos_objectif.x = -1;
			inf->pos_objectif.y = -1;
		}

		*cel = EXCIT_MUR;
	}
	else if(key == EXCIT_KEY_EVIDE) {

		if(*cel == EXCIT_JOUEUR) {
			inf->pos_joueur.x = -1;
			inf->pos_joueur.y = -1;
		}
		else if(*cel == EXCIT_OBJECTIF) {
			inf->pos_objectif.x = -1;
			inf->pos_objectif.y = -1;
		}

		*cel = EXCIT_VIDE;
	}
	else if(key == EXCIT_KEY_EJOUEUR && *cel != EXCIT_JOUEUR) {

		if(*cel == EXCIT_OBJECTIF) {
			inf->pos_objectif.x = -1;
			inf->pos_objectif.y = -1;
		}

		*cel = EXCIT_JOUEUR;

		if(inf->pos_joueur.x >= 0 && inf->pos_joueur.y >= 0) {
			matrix[inf->pos_joueur.x][inf->pos_joueur.y] = EXCIT_VIDE;
			save_cursor_pos();
			excit_refresh_case(&inf->pos_joueur, EXCIT_VIDE);
			restore_cursor_pos();
		}

		inf->pos_joueur = *cursor_pos;
	}
	else if(key == EXCIT_KEY_EOBJECTIF && *cel != EXCIT_OBJECTIF) {

		if(*cel == EXCIT_JOUEUR) {
			inf->pos_joueur.x = -1;
			inf->pos_joueur.y = -1;
		}

		*cel = EXCIT_OBJECTIF;

		if(inf->pos_objectif.x >= 0 && inf->pos_objectif.y >= 0) {
			matrix[inf->pos_objectif.x][inf->pos_objectif.y] = EXCIT_VIDE;
			save_cursor_pos();
			excit_refresh_case(&inf->pos_objectif, EXCIT_VIDE);
			restore_cursor_pos();
		}

		inf->pos_objectif = *cursor_pos;
	}
	else {
		return;
	}

	excit_refresh_case(NULL, *cel);
	curs_set(0);
	excit_refresh_editor_inf(inf);
	excit_move_cursor(key, cursor_pos);
	curs_set(1);
}

/*Charge le niveau grace au numérot du niveau, au nom du pack et place les info dans matrice, nom_niveau et nom_auteur
*/
int excit_charger_niveau(long niveau, char *filename, char matrice[1000], char nom_niveau[50], char nom_auteur[100], int *pos_joueur) {
	EXCIT_CASE_T matrix[EXCIT_MAT_X][EXCIT_MAT_Y];
	EXCIT_INF_T inf;
	char level[1000][50] = {{0}}, author[1000][100] = {{0}};
	long nb_level = 0, x = 0, y = 0, i = 0;

	nb_level = get_level_list(filename, level, author);

	if(nb_level != 0) {
		if(niveau > nb_level) {
			niveau = nb_level;
		}

		excit_init_to_default(matrix, &inf);
		excit_parse_file(filename, level, niveau, matrix, &inf);

		strcpy(nom_niveau, level[niveau]);
		strcpy(nom_auteur, author[niveau]);

		for(y = 0; y < EXCIT_MAT_Y; y++) {
			for(x = 0; x < EXCIT_MAT_X; x++) {
				switch(matrix[x][y]) {
				case EXCIT_VIDE:
					matrice[i] = EXCIT_FVIDE;
					break;
				case EXCIT_MUR:
					matrice[i] = EXCIT_FMUR;
					break;
				case EXCIT_BORD_DG:
					matrice[i] = EXCIT_FBORD_DG;
					break;
				case EXCIT_BORD_HB:
					matrice[i] = EXCIT_FBORD_HB;
					break;
				case EXCIT_JOUEUR:
					matrice[i] = EXCIT_FJOUEUR;
					*pos_joueur = i;
					break;
				case EXCIT_OBJECTIF:
					matrice[i] = EXCIT_FOBJECTIF;
					break;
				default:
					matrice[i] = EXCIT_FVIDE;
					break;
				}

				i++;
			}
		}
	}

	return nb_level;
}

int excit_parse_file(char *filename, char level[1000][50], int choix, EXCIT_CASE_T matrix[EXCIT_MAT_X][EXCIT_MAT_Y], EXCIT_INF_T *inf) {
	int x, y, numero_ligne = 0;
	char nom_ligne[10], buffer[100], level_name[100];

	sprintf(level_name, "%s", level[choix]);

	/* parsage du niveau */
	for(y = 0; y < EXCIT_MAT_Y; y++) {

		remove_ret_line(buffer);

		numero_ligne++;
		sprintf(nom_ligne, "ligne%d", numero_ligne);

		ini_gets(level_name, nom_ligne, "aap", buffer, sizearray(buffer), filename);

		for(x = 0; x < EXCIT_MAT_X; x++) {
			switch(buffer[x]) {
			case EXCIT_FMUR:
				matrix[x][y] = EXCIT_MUR;
				break;
			case EXCIT_FBORD_DG:
				matrix[x][y] = EXCIT_BORD_DG;
				break;
			case EXCIT_FBORD_HB:
				matrix[x][y] = EXCIT_BORD_HB;
				break;
			case EXCIT_FJOUEUR:
				matrix[x][y] = EXCIT_JOUEUR;
				inf->pos_joueur.x = x;
				inf->pos_joueur.y = y;
				break;
			case EXCIT_FOBJECTIF:
				matrix[x][y] = EXCIT_OBJECTIF;
				inf->pos_objectif.x = x;
				inf->pos_objectif.y = y;
				break;
			case EXCIT_FVIDE:
				matrix[x][y] = EXCIT_VIDE;
				break;
			default:
				matrix[x][y] = EXCIT_MUR;
				break;
			}
		}
	}


	return 0;
}

void excit_save_level(char *level_file, EXCIT_CASE_T matrix[EXCIT_MAT_X][EXCIT_MAT_Y], const char *author_name, const char *level_name) {
	int x, y, numero_ligne = 0;
	char nom_ligne[10];
	char buffer[64];

	ini_puts(level_name, "auteur", author_name, level_file);

	for(y = 0; y < EXCIT_MAT_Y; y++) {
		remove_ret_line(buffer);

		numero_ligne++;
		sprintf(nom_ligne, "ligne%d", numero_ligne);

		for(x = 0; x < EXCIT_MAT_X; x++) {
			switch(matrix[x][y]) {
			case EXCIT_VIDE:
				buffer[x] = EXCIT_FVIDE;
				break;
			case EXCIT_MUR:
				buffer[x] = EXCIT_FMUR;
				break;
			case EXCIT_BORD_DG:
				buffer[x] = EXCIT_FBORD_DG;
				break;
			case EXCIT_BORD_HB:
				buffer[x] = EXCIT_FBORD_HB;
				break;
			case EXCIT_JOUEUR:
				buffer[x] = EXCIT_FJOUEUR;
				break;
			case EXCIT_OBJECTIF:
				buffer[x] = EXCIT_FOBJECTIF;
				break;
			default:
				buffer[x] = EXCIT_FVIDE;
				break;
			}

			ini_puts(level_name, nom_ligne, buffer, level_file);
		}
	}
}

void excit_init_to_default(EXCIT_CASE_T matrix[EXCIT_MAT_X][EXCIT_MAT_Y], EXCIT_INF_T *inf) {
	int x, y;

	for(y = 0; y < EXCIT_MAT_Y; y++) {
		for(x = 0; x < EXCIT_MAT_X; x++) {
			if(y == 0 || y == EXCIT_MAT_Y - 1) {
				matrix[x][y] = EXCIT_BORD_HB;
			}
			else if(x == 0 || x == EXCIT_MAT_X - 1) {
				matrix[x][y] = EXCIT_BORD_DG;
			}
			else {
				matrix[x][y] = EXCIT_VIDE;
			}
		}
	}

	inf->pos_objectif.x = -1;
	inf->pos_objectif.y = -1;
	inf->pos_joueur.x = -1;
	inf->pos_joueur.y = -1;
}


